Bt.form.MoneyField = function(config)
{
    var defConfig = {
        autocomplete: 'off',
        allowNegative: true,
        format: 'BRL',
        currency: 'R$',
        showCurrency: true
    };
	
    Ext.applyIf(config, defConfig);
	
	if(!config.emptyText)
		config.emptyText = config.currency + ' 0,00';
	
    Bt.form.MoneyField.superclass.constructor.call(this, config);
};

Ext.extend(Bt.form.MoneyField, Ext.form.TextField, {
	
	initComponent: function()
	{
		if(!this.hiddenName){
            this.hiddenName = this.name;
			delete this.name;
        }
		
		switch (this.format) 
		{
            case 'USD':
                this.currencyPosition = 'left';
                this.currency = '$';
                break;
                
			case 'BRL' :	
            default:
                this.currency = 'R$ ';
                this.currencyPosition = 'left';
                break;
        }
			
		//super
		Bt.form.MoneyField.superclass.initComponent.call(this);
	}
	
    ,initEvents: function(){
        Bt.form.MoneyField.superclass.initEvents.call(this);
        this.el.on("keydown", this.stopEventFunction, this);
        this.el.on("keyup", this.mapCurrency, this);
        this.el.on("keypress", this.stopEventFunction, this);
    },
	
	setValue: function(v)
	{
		//transforma valor
		v = parseFloat(v);
		v = isNaN(v) ? "0,00" : v.toFixed(2);
		v += "";
		v = v.replace('.',',');
		
		//separa parte inteira e decimal
		v = v.split(',');
		var parteInt = v[0];
		var parteDec = v[1]
		var v = '';
		
		//coloca '.' na parte inteira a cada 3 digitos
		for(var i = 0, l=parteInt.length, l2=l-1 ; i <= l ; i++ )
		{
			if( i!== 0 && i % 3 === 0 )
				v = '.' + v;
				
			v = parteInt.charAt(l2-i) + v;
		}
		
		//junta novamente parte inteira e decimal
		v = v + ',' + parteDec;
		
		//atribui ao hidden
		if(this.hiddenField)
			this.hiddenField.value = v;
			
		//adiciona currency
		if( this.showCurrency )
		{
			if( this.currencyPosition == 'left' )
			{
				v = this.currency + v;
			}	
			else
			{
				v += this.currency;
			}
		}
		
		//atribui
		Bt.form.MoneyField.superclass.setValue.call(this,v);
	},
	
	onRender: function()
	{
		Bt.form.MoneyField.superclass.onRender.apply(this, arguments);
		
		if(this.hiddenName){
            this.hiddenField = this.el.insertSibling({tag:'input', type:'hidden', name: this.hiddenName,
                    id: (this.hiddenId||this.hiddenName)}, 'before', true);

            // prevent input submission
            this.el.dom.removeAttribute('name');
        }
	},
	
	// private
    onEnable : function(){
        Bt.form.MoneyField.superclass.onEnable.apply(this, arguments);
        if(this.hiddenField){
            this.hiddenField.disabled = false;
        }
    },

    // private
    onDisable : function(){
        Bt.form.MoneyField.superclass.onDisable.apply(this, arguments);
        if(this.hiddenField){
            this.hiddenField.disabled = true;
        }
    },
	
	// inherit docs
    getName: function(){
        var hf = this.hiddenField;
        return hf && hf.name ? hf.name : this.hiddenName || Bt.form.MoneyField.superclass.getName.call(this);
    },
	
	clearValue : function(){
        if(this.hiddenField){
            this.hiddenField.value = '';
        }
		
		Bt.form.MoneyField.superclass.clearValue.apply(this, arguments);
    },
	
	// private
    initValue : function()
	{
        Bt.form.MoneyField.superclass.initValue.call(this);
		
        if(this.hiddenField)
		{
            this.hiddenField.value =
                Ext.isDefined(this.hiddenValue) ? this.hiddenValue :
                Ext.isDefined(this.value) ? this.value : '';
        }
    },
    
    KEY_RANGES: {
        numeric: [48, 57],
        padnum: [96, 105]
    },
    
    isInRange: function(charCode, range){
        return charCode >= range[0] && charCode <= range[1];
    },
    
    formatCurrency: function(evt, floatPoint, decimalSep, thousandSep){
        floatPoint = !isNaN(floatPoint) ? Math.abs(floatPoint) : 2;
        thousandSep = typeof thousandSep != "string" ? "," : thousandSep;
        decimalSep = typeof decimalSep != "string" ? "." : decimalSep;
        var key = evt.getKey();
        
        if (this.isInRange(key, this.KEY_RANGES["padnum"])) {
            key -= 48;
        }
        
        this.sign = (this.allowNegative && (key == 45 || key == 109)) ? "-" : (key == 43 || key == 107 || key == 16) ? "" : this.sign;
        
        var character = (this.isInRange(key, this.KEY_RANGES["numeric"]) ? String.fromCharCode(key) : "");
        var field = this.el.dom;
        var value = (field.value.replace(/\D/g, "").replace(/^0+/g, "") + character).replace(/\D/g, "");
        var length = value.length;
        
        if (character == "" && length > 0 && key == 8) {
            length--;
            value = value.substr(0, length);
            evt.stopEvent();
        }
        
        if (field.maxLength + 1 && length >= field.maxLength) 
            return false;
        
        length <= floatPoint && (value = new Array(floatPoint - length + 2).join("0") + value);
        for (var i = (length = (value = value.split("")).length) - floatPoint; (i -= 3) > 0; value[i - 1] += thousandSep) 
            ;
        floatPoint && floatPoint < length && (value[length - ++floatPoint] += decimalSep);
        field.value = (this.showCurrency && this.currencyPosition == 'left' ? this.currency : '') +
        (this.sign ? this.sign : '') +
        value.join("") +
        (this.showCurrency && this.currencyPosition != 'left' ? this.currency : '');
		
		if(this.hiddenField){
            this.hiddenField.value = value.join("");
        }
		
    },
    
    mapCurrency: function(evt){
        switch (this.format) {
            case 'BRL':
                this.formatCurrency(evt, 2, ',', '.');
                break;
                
            case 'USD':
                this.formatCurrency(evt, 2);
                break;
                
            default:
                this.formatCurrency(evt, 2);
        }
    },
    
    stopEventFunction: function(evt){
        var key = evt.getKey();
        
        if (this.isInRange(key, this.KEY_RANGES["padnum"])) {
            key -= 48;
        }
        		
        if (((key >= 41 && key <= 122) || key == 32 || key == 8 || key > 186) && (!evt.altKey && !evt.ctrlKey)) {
            evt.stopEvent();
        }
    },
    
    getCharForCode: function(keyCode){
        var chr = '';
        switch (keyCode) {
            case 48:
            case 96: // 0 and numpad 0
                chr = '0';
                break;
                
            case 49:
            case 97: // 1 and numpad 1
                chr = '1';
                break;
                
            case 50:
            case 98: // 2 and numpad 2
                chr = '2';
                break;
                
            case 51:
            case 99: // 3 and numpad 3
                chr = '3';
                break;
                
            case 52:
            case 100: // 4 and numpad 4
                chr = '4';
                break;
                
            case 53:
            case 101: // 5 and numpad 5
                chr = '5';
                break;
                
            case 54:
            case 102: // 6 and numpad 6
                chr = '6';
                break;
                
            case 55:
            case 103: // 7 and numpad 7
                chr = '7';
                break;
                
            case 56:
            case 104: // 8 and numpad 8
                chr = '8';
                break;
                
            case 57:
            case 105: // 9 and numpad 9
                chr = '9';
                break;
                
            case 45:
            case 189:
            case 109:
                chr = '-';
                break;
                
            case 43:
            case 107:
            case 187:
                chr = '+';
                break;
                
            default:
                chr = String.fromCharCode(keyCode); // key pressed as a lowercase string
                break;
        }
        return chr;
    }
});
Ext.reg('moneyfield', Bt.form.MoneyField);